home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / boot / czesc_2 / toolmanager / source / prefs / docklistwindow.c < prev    next >
C/C++ Source or Header  |  1993-05-15  |  22KB  |  750 lines

  1. /*
  2.  * docklistwindow.c  V2.1
  3.  *
  4.  * dock list edit window handling
  5.  *
  6.  * (c) 1990-1993 Stefan Becker
  7.  */
  8.  
  9. #include "ToolManagerConf.h"
  10.  
  11. /* Window data */
  12. static struct Gadget *gl;             /* Gadget list */
  13. static struct Window *w;              /* Window */
  14. static struct MsgPort *wp;            /* Window user port */
  15. static UWORD ww,wh;                   /* Window size */
  16. static struct List *ToolsList;
  17. static struct ToolNode *CurrentTool;
  18. static LONG CurrentTop;               /* Top tool ordinal number */
  19. static LONG CurrentOrd;               /* Current tool ordinal number */
  20. static ULONG CurrentGadgetNum;
  21. static BOOL ReqOpen;
  22. static struct Requester DummyReq;
  23. #define WINDOW_IDCMP (IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|BUTTONIDCMP|\
  24.                       LISTVIEWIDCMP|TEXTIDCMP|IDCMP_VANILLAKEY)
  25.  
  26. /* Gadget data */
  27. #define GAD_TOOLS       0
  28. #define GAD_NEW         1
  29. #define GAD_REMOVE      2
  30. #define GAD_TOP         3
  31. #define GAD_UP          4
  32. #define GAD_DOWN        5
  33. #define GAD_BOTTOM      6
  34. #define GAD_EXEC_BUT    7
  35. #define GAD_EXEC_TXT    8
  36. #define GAD_IMAGE_BUT   9
  37. #define GAD_IMAGE_TXT  10
  38. #define GAD_SOUND_BUT  11
  39. #define GAD_SOUND_TXT  12
  40. #define GAD_OK         13
  41. #define GAD_CANCEL     14
  42. #define GADGETS        15
  43. static struct GadgetData gdata[GADGETS];
  44.  
  45. /* Gadget tags */
  46. static struct TagItem lvtags[]={GTLV_Labels, NULL,
  47.                                 TAG_DONE};
  48.  
  49. static struct TagItem exectags[]={GTTX_Text,   NULL,
  50.                                   GTTX_Border, TRUE,
  51.                                   TAG_DONE};
  52.  
  53. static struct TagItem imagetags[]={GTTX_Text,   NULL,
  54.                                    GTTX_Border, TRUE,
  55.                                    TAG_DONE};
  56.  
  57. static struct TagItem soundtags[]={GTTX_Text,   NULL,
  58.                                    GTTX_Border, TRUE,
  59.                                    TAG_DONE};
  60.  
  61. /* Gadget vanilla key data */
  62. #define KEY_NEW    0
  63. #define KEY_EXEC   1
  64. #define KEY_IMAGE  2
  65. #define KEY_SOUND  3
  66. #define KEY_OK     4
  67. #define KEY_CANCEL 5
  68. static char KeyArray[KEY_CANCEL+1];
  69.  
  70. /* Init dock list edit window */
  71. void InitDockListEditWindow(UWORD left, UWORD fheight)
  72. {
  73.  ULONG i,tmp,tmp2,tmp3,maxw1,maxw2,maxw3;
  74.  ULONG strheight=fheight+2;
  75.  struct GadgetData *gd;
  76.  
  77.  /* Init strings */
  78.  gdata[GAD_TOOLS].name  =AppStrings[MSG_DOCKLISTWIN_TOOLS_GAD];
  79.  gdata[GAD_NEW].name    =AppStrings[MSG_DOCKLISTWIN_NEW_GAD];
  80.  gdata[GAD_REMOVE].name =AppStrings[MSG_WINDOW_REMOVE_GAD];
  81.  gdata[GAD_TOP].name    =AppStrings[MSG_WINDOW_TOP_GAD];
  82.  gdata[GAD_UP].name     =AppStrings[MSG_WINDOW_UP_GAD];
  83.  gdata[GAD_DOWN].name   =AppStrings[MSG_WINDOW_DOWN_GAD];
  84.  gdata[GAD_BOTTOM].name =AppStrings[MSG_WINDOW_BOTTOM_GAD];
  85.  gdata[GAD_OK].name     =AppStrings[MSG_WINDOW_OK_GAD];
  86.  gdata[GAD_CANCEL].name =AppStrings[MSG_WINDOW_CANCEL_GAD];
  87.  
  88.  /* Calculate width for listview gadget */
  89.  gd=gdata;
  90.  ww=2*TextLength(&TmpRastPort,gd->name,strlen(gd->name));
  91.  if ((tmp=ListViewColumns*ScreenFont->tf_XSize) > ww) ww=tmp;
  92.  
  93.  /* Calculate maximum width for tools gadgets */
  94.  maxw1=0;
  95.  for (gd++, i=GAD_NEW; i<=GAD_BOTTOM; i++, gd++)
  96.   if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > maxw1)
  97.    maxw1=tmp;
  98.  maxw1+=2*INTERWIDTH;
  99.  ww+=2*maxw1+3*INTERWIDTH;
  100.  
  101.  /* Calculate maximum label width for text gadgets */
  102.  {
  103.   char **s;
  104.  
  105.   maxw2=0;
  106.   s=&AppStrings[MSG_WINDOW_EXEC_GAD];
  107.   for (i=MSG_WINDOW_EXEC_GAD; i<=MSG_WINDOW_SOUND_GAD; i++, s++)
  108.    if ((tmp=TextLength(&TmpRastPort,*s,strlen(*s))) > maxw2) maxw2=tmp;
  109.   maxw2+=2*INTERWIDTH;
  110.  }
  111.  
  112.  /* Calculate minimal width for text gadgets */
  113.  tmp=TextLength(&TmpRastPort,AppStrings[MSG_LISTREQ_TITLE_EXEC],
  114.                strlen(AppStrings[MSG_LISTREQ_TITLE_EXEC]))+3*INTERWIDTH;
  115.  if ((tmp+=maxw2) > ww) ww=tmp;
  116.  
  117.  /* Calculate button gadgets width */
  118.  gd=&gdata[GAD_OK];
  119.  maxw3=TextLength(&TmpRastPort,gd->name,strlen(gd->name));
  120.  gd++;
  121.  if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name)))
  122.      > maxw3)
  123.   maxw3=tmp;
  124.  maxw3+=2*INTERWIDTH;
  125.  if ((tmp=2*(maxw3+INTERWIDTH)) > ww) ww=tmp;
  126.  
  127.  /* window height */
  128.  wh=(ListViewRows+3)*fheight+6*INTERHEIGHT+6;
  129.  
  130.  /* Init gadgets */
  131.  gd=gdata;
  132.  tmp=WindowTop+fheight+INTERHEIGHT;
  133.  
  134.  /* Tools list gadget */
  135.  gd->type=LISTVIEW_KIND;
  136.  gd->flags=PLACETEXT_ABOVE;
  137.  gd->tags=lvtags;
  138.  gd->left=left+maxw1+INTERWIDTH;
  139.  gd->top=tmp;
  140.  gd->width=ww-3*INTERWIDTH-2*maxw1;
  141.  gd->height=(ListViewRows-2)*fheight;
  142.  
  143.  /* New gadget */
  144.  gd++;
  145.  tmp2=tmp+((ListViewRows-4)*fheight-INTERHEIGHT)/2;
  146.  gd->type=BUTTON_KIND;
  147.  gd->flags=PLACETEXT_IN;
  148.  gd->left=left;
  149.  gd->top=tmp2;
  150.  gd->width=maxw1;
  151.  gd->height=fheight;
  152.  
  153.  /* Remove gadget */
  154.  gd++;
  155.  gd->type=BUTTON_KIND;
  156.  gd->flags=PLACETEXT_IN;
  157.  gd->tags=DisabledTags;
  158.  gd->left=left;
  159.  gd->top=tmp2+fheight+INTERHEIGHT;
  160.  gd->width=maxw1;
  161.  gd->height=fheight;
  162.  
  163.  /* Move gadgets */
  164.  gd++;
  165.  tmp2=tmp+((ListViewRows-6)*fheight-3*INTERHEIGHT)/2;
  166.  tmp3=ww-maxw1-INTERWIDTH+left;
  167.  for (i=GAD_TOP; i<=GAD_BOTTOM; i++, gd++, tmp2+=fheight+INTERHEIGHT) {
  168.   gd->type=BUTTON_KIND;
  169.   gd->flags=PLACETEXT_IN;
  170.   gd->tags=DisabledTags;
  171.   gd->left=tmp3;
  172.   gd->top=tmp2;
  173.   gd->width=maxw1;
  174.   gd->height=fheight;
  175.  }
  176.  tmp+=(ListViewRows-2)*fheight+INTERHEIGHT;
  177.  
  178.  /* Exec object button gadget */
  179.  i=strheight+INTERHEIGHT;
  180.  tmp2=ww-maxw2-2*INTERWIDTH;
  181.  maxw1=maxw2+left+INTERWIDTH;
  182.  gd->name=AppStrings[MSG_WINDOW_EXEC_GAD];
  183.  gd->type=BUTTON_KIND;
  184.  gd->flags=PLACETEXT_IN;
  185.  gd->tags=DisabledTags;
  186.  gd->left=left;
  187.  gd->top=tmp;
  188.  gd->width=maxw2;
  189.  gd->height=strheight;
  190.  
  191.  /* Exec object text gadget */
  192.  gd++;
  193.  gd->type=TEXT_KIND;
  194.  gd->tags=exectags;
  195.  gd->left=maxw1;
  196.  gd->top=tmp;
  197.  gd->width=tmp2;
  198.  gd->height=strheight;
  199.  tmp+=i;
  200.  
  201.  /* Image object button gadget */
  202.  gd++;
  203.  gd->name=AppStrings[MSG_WINDOW_IMAGE_GAD];
  204.  gd->type=BUTTON_KIND;
  205.  gd->flags=PLACETEXT_IN;
  206.  gd->tags=DisabledTags;
  207.  gd->left=left;
  208.  gd->top=tmp;
  209.  gd->width=maxw2;
  210.  gd->height=strheight;
  211.  
  212.  /* Image object text gadget */
  213.  gd++;
  214.  gd->type=TEXT_KIND;
  215.  gd->tags=imagetags;
  216.  gd->left=maxw1;
  217.  gd->top=tmp;
  218.  gd->width=tmp2;
  219.  gd->height=strheight;
  220.  tmp+=i;
  221.  
  222.  /* Sound object button gadget */
  223.  gd++;
  224.  gd->name=AppStrings[MSG_WINDOW_SOUND_GAD];
  225.  gd->type=BUTTON_KIND;
  226.  gd->flags=PLACETEXT_IN;
  227.  gd->tags=DisabledTags;
  228.  gd->left=left;
  229.  gd->top=tmp;
  230.  gd->width=maxw2;
  231.  gd->height=strheight;
  232.  
  233.  /* Sound object text gadget */
  234.  gd++;
  235.  gd->type=TEXT_KIND;
  236.  gd->tags=soundtags;
  237.  gd->left=maxw1;
  238.  gd->top=tmp;
  239.  gd->width=tmp2;
  240.  gd->height=strheight;
  241.  tmp+=i;
  242.  
  243.  /* OK button gadget */
  244.  gd++;
  245.  gd->type=BUTTON_KIND;
  246.  gd->flags=PLACETEXT_IN;
  247.  gd->left=left;
  248.  gd->top=tmp;
  249.  gd->width=maxw3;
  250.  gd->height=fheight;
  251.  
  252.  /* Cancel button gadget */
  253.  gd++;
  254.  gd->type=BUTTON_KIND;
  255.  gd->flags=PLACETEXT_IN;
  256.  gd->left=ww-maxw3-INTERWIDTH+left;
  257.  gd->top=tmp;
  258.  gd->width=maxw3;
  259.  gd->height=fheight;
  260.  
  261.  /* Init vanilla key array */
  262.  KeyArray[KEY_NEW]   =FindVanillaKey(gdata[GAD_NEW].name);
  263.  KeyArray[KEY_EXEC]  =FindVanillaKey(gdata[GAD_EXEC_BUT].name);
  264.  KeyArray[KEY_IMAGE] =FindVanillaKey(gdata[GAD_IMAGE_BUT].name);
  265.  KeyArray[KEY_SOUND] =FindVanillaKey(gdata[GAD_SOUND_BUT].name);
  266.  KeyArray[KEY_OK]    =FindVanillaKey(gdata[GAD_OK].name);
  267.  KeyArray[KEY_CANCEL]=FindVanillaKey(gdata[GAD_CANCEL].name);
  268.  
  269.  /* Init dummy requester structure */
  270.  InitRequester(&DummyReq);
  271. }
  272.  
  273. /* Free tool list */
  274. void FreeToolsList(struct List *toollist)
  275. {
  276.  struct ToolNode *tn1,*tn2=GetHead(toollist);
  277.  
  278.  /* Free tool nodes */
  279.  while (tn1=tn2) {
  280.   char *s;
  281.  
  282.   /* Get next node */
  283.   tn2=GetSucc(tn1);
  284.  
  285.   /* Remove node */
  286.   Remove((struct Node *) tn1);
  287.  
  288.   /* Free node */
  289.   if (s=tn1->tn_Node.ln_Name) free(s);
  290.   if (s=tn1->tn_Image) free(s);
  291.   if (s=tn1->tn_Sound) free(s);
  292.   FreeMem(tn1,sizeof(struct ToolNode));
  293.  }
  294.  free(toollist);
  295. }
  296.  
  297. /* Copy tools list */
  298. struct List *CopyToolsList(struct List *srclist)
  299. {
  300.  struct List *destlist;
  301.  
  302.  /* Allocate new list */
  303.  if (destlist=malloc(sizeof(struct List))) {
  304.   /* Init new list */
  305.   NewList(destlist);
  306.  
  307.   /* Valid source list? */
  308.   if (srclist) {
  309.    struct ToolNode *origtool=GetHead(srclist);
  310.  
  311.    /* Scan tools list */
  312.    while (origtool) {
  313.     struct ToolNode *newtool;
  314.  
  315.     if ((newtool=AllocMem(sizeof(struct ToolNode),MEMF_PUBLIC|MEMF_CLEAR)) &&
  316.         (!origtool->tn_Node.ln_Name || (newtool->tn_Node.ln_Name=
  317.                                          strdup(origtool->tn_Node.ln_Name))) &&
  318.         (!origtool->tn_Image || (newtool->tn_Image=
  319.                                   strdup(origtool->tn_Image))) &&
  320.         (!origtool->tn_Sound || (newtool->tn_Sound=
  321.                                   strdup(origtool->tn_Sound))))
  322.      AddTail(destlist,(struct Node *) newtool);
  323.     else {
  324.      char *s;
  325.  
  326.      /* Error, free new node */
  327.      if (s=newtool->tn_Node.ln_Name) free(s);
  328.      if (s=newtool->tn_Image) free(s);
  329.      if (s=newtool->tn_Sound) free(s);
  330.      FreeMem(newtool,sizeof(struct ToolNode));
  331.      FreeToolsList(destlist);
  332.      return(NULL);
  333.     }
  334.  
  335.     /* Get next node */
  336.     origtool=GetSucc(origtool);
  337.    }
  338.   }
  339.  }
  340.  return(destlist);
  341. }
  342.  
  343. /* Open dock list edit window */
  344. BOOL OpenDockListEditWindow(struct List *oldlist, struct Window *parent)
  345. {
  346.  /* Copy node */
  347.  if (ToolsList=CopyToolsList(oldlist)) {
  348.   /* Set tags */
  349.   lvtags[0].ti_Data=(ULONG) ToolsList;
  350.  
  351.   /* Create gadgets */
  352.   if (gl=CreateGadgetList(gdata,GADGETS)) {
  353.    /* Open window */
  354.    if (w=OpenWindowTags(NULL,WA_Left,        parent->LeftEdge,
  355.                              WA_Top,         parent->TopEdge+WindowTop,
  356.                              WA_InnerWidth,  ww,
  357.                              WA_InnerHeight, wh,
  358.                              WA_AutoAdjust,  TRUE,
  359.                              WA_Title,       AppStrings[MSG_DOCKLISTWIN_TITLE],
  360.                              WA_PubScreen,   PublicScreen,
  361.                              WA_Flags,       WFLG_CLOSEGADGET|WFLG_DRAGBAR|
  362.                                              WFLG_DEPTHGADGET|WFLG_RMBTRAP|
  363.                                              WFLG_ACTIVATE,
  364.                              TAG_DONE)) {
  365.     /* Add gadgets to window */
  366.     AddGList(w,gl,(UWORD) -1,(UWORD) -1,NULL);
  367.     RefreshGList(gl,w,NULL,(UWORD) -1);
  368.     GT_RefreshWindow(w,NULL);
  369.  
  370.     /* Set local variables */
  371.     w->UserPort=IDCMPPort;
  372.     w->UserData=(BYTE *) HandleDockListEditWindowIDCMP;
  373.     ModifyIDCMP(w,WINDOW_IDCMP);
  374.     CurrentWindow=w;
  375.     ReqOpen=FALSE;
  376.     CurrentTool=NULL;
  377.     CurrentTop=0;
  378.     CurrentOrd=-1;
  379.  
  380.     /* All OK. */
  381.     return(TRUE);
  382.    }
  383.    FreeGadgets(gl);
  384.   }
  385.   FreeToolsList(ToolsList);
  386.  }
  387.  /* Call failed */
  388.  return(FALSE);
  389. }
  390.  
  391. /* Close dock edit window */
  392. static void CloseDockListEditWindow(void)
  393. {
  394.  /* Free resources */
  395.  RemoveGList(w,gl,(UWORD) -1);
  396.  CloseWindowSafely(w);
  397.  FreeGadgets(gl);
  398. }
  399.  
  400. /* Detach list */
  401. static void DetachToolList(void)
  402. {
  403.  GT_SetGadgetAttrs(gdata[GAD_TOOLS].gadget,w,NULL,GTLV_Labels,-1,
  404.                                                   TAG_DONE);
  405. }
  406.  
  407. /* Attach list */
  408. static void AttachToolList(void)
  409. {
  410.  GT_SetGadgetAttrs(gdata[GAD_TOOLS].gadget,w,NULL,GTLV_Labels,   ToolsList,
  411.                                                   GTLV_Top,      CurrentTop,
  412.                                                   GTLV_Selected, CurrentOrd,
  413.                                                   TAG_DONE);
  414. }
  415.  
  416. /* Disable tool gadgets */
  417. static void DisableToolGadgets(BOOL disable)
  418. {
  419.  DisableGadget(gdata[GAD_REMOVE].gadget,w,disable);
  420.  DisableGadget(gdata[GAD_TOP].gadget,w,disable);
  421.  DisableGadget(gdata[GAD_UP].gadget,w,disable);
  422.  DisableGadget(gdata[GAD_DOWN].gadget,w,disable);
  423.  DisableGadget(gdata[GAD_BOTTOM].gadget,w,disable);
  424.  DisableGadget(gdata[GAD_EXEC_BUT].gadget,w,disable);
  425.  DisableGadget(gdata[GAD_IMAGE_BUT].gadget,w,disable);
  426.  DisableGadget(gdata[GAD_SOUND_BUT].gadget,w,disable);
  427. }
  428.  
  429. /* Set text gadget */
  430. static void SetTextGadget(ULONG num, char *text)
  431. {
  432.  GT_SetGadgetAttrs(gdata[num].gadget,w,NULL,GTTX_Text, text,
  433.                                             TAG_DONE);
  434. }
  435.  
  436. /* New gadget function */
  437. static void NewGadgetFunc(void)
  438. {
  439.  struct ToolNode *tn;
  440.  
  441.  /* Create dummy tool */
  442.  if (tn=AllocMem(sizeof(struct ToolNode),MEMF_PUBLIC|MEMF_CLEAR))
  443.   if (tn->tn_Node.ln_Name=strdup(AppStrings[MSG_LISTREQ_TITLE_EXEC])) {
  444.    /* Detach tool list */
  445.    DetachToolList();
  446.  
  447.    /* Insert new node */
  448.    if (CurrentTool) {
  449.     /* Insert after current Tool */
  450.     Insert(ToolsList, (struct Node *) tn, (struct Node *) CurrentTool);
  451.     CurrentTop++;
  452.     CurrentOrd++;
  453.    } else {
  454.     /* Append to list */
  455.     struct Node *tmpnode;
  456.     ULONG i;
  457.  
  458.     /* Add node to the end of list */
  459.     AddTail(ToolsList,(struct Node *) tn);
  460.  
  461.     /* Search ordinal number */
  462.     tmpnode=GetHead(ToolsList);
  463.     for (i=0; tmpnode; i++) tmpnode=GetSucc(tmpnode);
  464.     CurrentOrd=--i;
  465.     CurrentTop=(i>ListViewRows-5) ? i-ListViewRows+5 : 0;
  466.  
  467.     /* Enable tool gadgets */
  468.     DisableToolGadgets(FALSE);
  469.    }
  470.    CurrentTool=tn;
  471.  
  472.    /* Set text gadgets */
  473.    SetTextGadget(GAD_EXEC_TXT,tn->tn_Node.ln_Name);
  474.    SetTextGadget(GAD_IMAGE_TXT,NULL);
  475.    SetTextGadget(GAD_SOUND_TXT,NULL);
  476.  
  477.    /* Attach tool list */
  478.    AttachToolList();
  479.   } else
  480.    /* Error */
  481.    FreeMem(tn,sizeof(struct ToolNode));
  482. }
  483.  
  484. /* Exec, Image & Sound button gadget function */
  485. static void TextButtonGadgetFunc(ULONG gadnum, ULONG listnum)
  486. {
  487.  if (!ReqOpen) {
  488.   /* Save gadget number */
  489.   CurrentGadgetNum=gadnum;
  490.  
  491.   /* Open list requester */
  492.   if (OpenListRequester(listnum,w)) {
  493.    /* Disable window */
  494.    DisableWindow(w,&DummyReq);
  495.  
  496.    /* Set update function */
  497.    UpdateWindow=UpdateDockListEditWindow;
  498.    ReqOpen=TRUE;
  499.   }
  500.  }
  501. }
  502.  
  503. /* Handle dock list edit window IDCMP events */
  504. void *HandleDockListEditWindowIDCMP(struct IntuiMessage *msg)
  505. {
  506.  struct List *NewList=NULL;
  507.  
  508.  /* Which IDCMP class? */
  509.  switch (msg->Class) {
  510.   case IDCMP_CLOSEWINDOW:   NewList=(struct List *) -1;
  511.                             FreeToolsList(ToolsList);
  512.                             break;
  513.   case IDCMP_REFRESHWINDOW: GT_BeginRefresh(w);
  514.                             GT_EndRefresh(w,TRUE);
  515.                             break;
  516.   case IDCMP_GADGETUP:
  517.    switch (((struct Gadget *) msg->IAddress)->GadgetID) {
  518.     case GAD_TOOLS:     {
  519.                          ULONG i;
  520.  
  521.                          /* Find node */
  522.                          CurrentTop=(msg->Code>ListViewRows-5) ?
  523.                           msg->Code-ListViewRows+5 : 0;
  524.                          CurrentOrd=msg->Code;
  525.                          CurrentTool=GetHead(ToolsList);
  526.                          for (i=0; i<CurrentOrd; i++)
  527.                           CurrentTool=GetSucc(CurrentTool);
  528.  
  529.                          /* Set text gadgets */
  530.                          SetTextGadget(GAD_EXEC_TXT,
  531.                                        CurrentTool->tn_Node.ln_Name);
  532.                          SetTextGadget(GAD_IMAGE_TXT,CurrentTool->tn_Image);
  533.                          SetTextGadget(GAD_SOUND_TXT,CurrentTool->tn_Sound);
  534.  
  535.                          /* Activate object gadgets */
  536.                          DisableToolGadgets(FALSE);
  537.                         }
  538.                         break;
  539.     case GAD_NEW:       NewGadgetFunc();
  540.                         break;
  541.     case GAD_REMOVE:    if (CurrentTool) {
  542.                          char *s;
  543.  
  544.                          /* Detach tool list */
  545.                          DetachToolList();
  546.  
  547.                          /* Disable tool gadgets */
  548.                          DisableToolGadgets(TRUE);
  549.  
  550.                          /* Set text gadgets */
  551.                          SetTextGadget(GAD_EXEC_TXT,NULL);
  552.                          SetTextGadget(GAD_IMAGE_TXT,NULL);
  553.                          SetTextGadget(GAD_SOUND_TXT,NULL);
  554.  
  555.                          /* Remove Node */
  556.                          Remove((struct Node *) CurrentTool);
  557.  
  558.                          /* Free Node */
  559.                          if (s=CurrentTool->tn_Node.ln_Name) free(s);
  560.                          if (s=CurrentTool->tn_Image) free(s);
  561.                          if (s=CurrentTool->tn_Sound) free(s);
  562.                          FreeMem(CurrentTool,sizeof(struct ToolNode));
  563.  
  564.                          /* Reset pointers */
  565.                          CurrentTool=NULL;
  566.                          if (CurrentTop) CurrentTop--;
  567.                          CurrentOrd=-1;
  568.  
  569.                          /* Attach tool list */
  570.                          AttachToolList();
  571.                         }
  572.                         break;
  573.     case GAD_TOP:       if (CurrentTool) {
  574.                          /* Detach tool list */
  575.                          DetachToolList();
  576.  
  577.                          /* Move node to top of list */
  578.                          Remove((struct Node *) CurrentTool);
  579.                          AddHead(ToolsList,(struct Node *) CurrentTool);
  580.                          CurrentTop=0;
  581.                          CurrentOrd=0;
  582.  
  583.                          /* Attach tool list */
  584.                          AttachToolList();
  585.                         }
  586.                         break;
  587.     case GAD_UP:        {
  588.                          struct Node *pred;
  589.  
  590.                          /* Node valid and has a predecessor? */
  591.                          if (CurrentTool && (pred=GetPred(CurrentTool))) {
  592.                           /* Detach tool list */
  593.                           DetachToolList();
  594.  
  595.                           /* Move node one position up */
  596.                           pred=GetPred(pred);
  597.                           Remove((struct Node *) CurrentTool);
  598.                           Insert(ToolsList,(struct Node *) CurrentTool,pred);
  599.                           --CurrentOrd;
  600.                           CurrentTop=(CurrentOrd>ListViewRows-5) ?
  601.                            CurrentOrd-ListViewRows+5 : 0;
  602.  
  603.                           /* Attach tool list */
  604.                           AttachToolList();
  605.                          }
  606.                         }
  607.                         break;
  608.     case GAD_DOWN:      {
  609.                          struct Node *succ;
  610.  
  611.                          /* Node valid and has a successor? */
  612.                          if (CurrentTool && (succ=GetSucc(CurrentTool))) {
  613.                           /* Detach tool list */
  614.                           DetachToolList();
  615.  
  616.                           /* Move node one position down */
  617.                           Remove((struct Node *) CurrentTool);
  618.                           Insert(ToolsList,(struct Node *) CurrentTool,succ);
  619.                           ++CurrentOrd;
  620.                           CurrentTop=(CurrentOrd>ListViewRows-5) ?
  621.                            CurrentOrd-ListViewRows+5 : 0;
  622.  
  623.                           /* Attach tool list */
  624.                           AttachToolList();
  625.                          }
  626.                         }
  627.                         break;
  628.     case GAD_BOTTOM:    if (CurrentTool) {
  629.                          ULONG i;
  630.                          struct Node *tmpnode;
  631.  
  632.                          /* Detach tool list */
  633.                          DetachToolList();
  634.  
  635.                          /* Move tool to bottom of list */
  636.                          Remove((struct Node *) CurrentTool);
  637.                          AddTail(ToolsList,(struct Node *) CurrentTool);
  638.  
  639.                          /* Search ordinal number */
  640.                          tmpnode=GetHead(ToolsList);
  641.                          for (i=0; tmpnode; i++) tmpnode=GetSucc(tmpnode);
  642.                          CurrentOrd=--i;
  643.                          CurrentTop=(i>ListViewRows-5) ? i-ListViewRows+5 : 0;
  644.  
  645.                          /* Attach tool list */
  646.                          AttachToolList();
  647.                         }
  648.                         break;
  649.     case GAD_EXEC_BUT:  TextButtonGadgetFunc(GAD_EXEC_TXT,LISTREQ_EXEC);
  650.                         break;
  651.     case GAD_IMAGE_BUT: TextButtonGadgetFunc(GAD_IMAGE_TXT,LISTREQ_IMAGE);
  652.                         break;
  653.     case GAD_SOUND_BUT: TextButtonGadgetFunc(GAD_SOUND_TXT,LISTREQ_SOUND);
  654.                         break;
  655.     case GAD_OK:        NewList=ToolsList;
  656.                         break;
  657.     case GAD_CANCEL:    NewList=(struct List *) -1;
  658.                         FreeToolsList(ToolsList);
  659.                         break;
  660.    }
  661.    break;
  662.   case IDCMP_VANILLAKEY:
  663.    switch (MatchVanillaKey(msg->Code,KeyArray)) {
  664.     case KEY_NEW:    NewGadgetFunc();
  665.                      break;
  666.     case KEY_EXEC:   TextButtonGadgetFunc(GAD_EXEC_TXT,LISTREQ_EXEC);
  667.                      break;
  668.     case KEY_IMAGE:  TextButtonGadgetFunc(GAD_IMAGE_TXT,LISTREQ_IMAGE);
  669.                      break;
  670.     case KEY_SOUND:  TextButtonGadgetFunc(GAD_SOUND_TXT,LISTREQ_SOUND);
  671.                      break;
  672.     case KEY_OK:     NewList=ToolsList;
  673.                      break;
  674.     case KEY_CANCEL: NewList=(struct List *) -1;
  675.                      FreeToolsList(ToolsList);
  676.                      break;
  677.    }
  678.    break;
  679.  }
  680.  
  681.  /* Close window? */
  682.  if (NewList) {
  683.   /* Yes. But first reply message!!! */
  684.   GT_ReplyIMsg(msg);
  685.   CloseDockListEditWindow();
  686.  }
  687.  
  688.  return(NewList);
  689. }
  690.  
  691. /* Update dock edit window */
  692. void UpdateDockListEditWindow(void *data)
  693. {
  694.  /* Got data? */
  695.  if (data != LREQRET_CANCEL) {
  696.   char *new;
  697.  
  698.   /* Selected something? */
  699.   new=(data == LREQRET_NOSELECT) ? NULL : ((struct Node *) data)->ln_Name;
  700.  
  701.   /* Duplicate name */
  702.   if (!new || (new=strdup(new))) {
  703.    char *old;
  704.  
  705.    /* Which object? */
  706.    switch (CurrentGadgetNum) {
  707.     case GAD_EXEC_TXT:  /* Detach tool list */
  708.                         DetachToolList();
  709.  
  710.                         /* Set new Exec name */
  711.                         old=CurrentTool->tn_Node.ln_Name;
  712.  
  713.                         /* Set VALID name! */
  714.                         if (new || (new=strdup(
  715.                                          AppStrings[MSG_LISTREQ_TITLE_EXEC])))
  716.                          CurrentTool->tn_Node.ln_Name=new;
  717.                         else
  718.                          /* Could not set valid name */
  719.                          old=NULL;
  720.  
  721.                         /* Attach tool list */
  722.                         AttachToolList();
  723.                         break;
  724.     case GAD_IMAGE_TXT: /* Set new Image name */
  725.                         old=CurrentTool->tn_Image;
  726.                         CurrentTool->tn_Image=new;
  727.                         break;
  728.     case GAD_SOUND_TXT: /* Set new Sound name */
  729.                         old=CurrentTool->tn_Sound;
  730.                         CurrentTool->tn_Sound=new;
  731.                         break;
  732.    }
  733.  
  734.    /* Free old string */
  735.    if (old) free(old);
  736.  
  737.    /* Set new text */
  738.    SetTextGadget(CurrentGadgetNum,new);
  739.   }
  740.  }
  741.  
  742.  /* Enable window */
  743.  EnableWindow(w,&DummyReq,WINDOW_IDCMP);
  744.  
  745.  /* Restore update function pointer */
  746.  UpdateWindow=UpdateDockEditWindow;
  747.  CurrentWindow=w;
  748.  ReqOpen=FALSE;
  749. }
  750.